package com.freewater.javabase.demo.mutithread.threadpool;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ExecutorsShutDown {

    public static void main(String[] args) throws InterruptedException {
        shutdown();
        System.out.println("---------------------------");
        shutdownNow();
        System.out.println("---------------------------");
        awaitTermination();
    }

    private static void shutdown() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 4; i++) {
            executorService.execute(new Task(i));
        }
        // 告诉线程池，没有更多任务需要添加到它的内部队列，并且一旦完成所有等待的工作就应当关闭:
        executorService.shutdown();
        while (!executorService.isTerminated()) {
            System.out.println("thread main 线程池还没有完全关闭");
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println("thread main 线程池完全关闭");
    }

    private static void shutdownNow() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 0; i < 4; i++) {
            executorService.execute(new Task(i));
        }
        // 通知所有正在运行的任务关闭（通过调用正在运行任务线程的interrupt()方法），忽略所有等待任务，并返回正处于等待状态的任务列表
        TimeUnit.SECONDS.sleep(3);
        final List<Runnable> waitingTasks = executorService.shutdownNow();
        System.out.println("thread main 线程池完全关闭");
        printUnExecutedTasks(waitingTasks);
    }

    private static void awaitTermination() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        for (int i = 0; i < 4; i++) {
            executorService.execute(new Task(i));
        }
        // 告诉线程池，没有更多任务需要添加到它的内部队列，并且一旦完成所有等待的工作就应当关闭:
        executorService.shutdown();
        // 等待2秒(只给还未执行的任务2秒时间)，如果线程池任没有完全关闭则强制关闭
        System.out.println("thread main waiting 2 seconds, or else shutdownNow");
        final boolean terminated = executorService.awaitTermination(2, TimeUnit.SECONDS);
        if (!terminated) {
            // 通知所有正在运行的任务关闭（通过调用正在运行任务线程的interrupt()方法），忽略所有等待任务，并返回正处于等待状态的任务列表
            final List<Runnable> tasks = executorService.shutdownNow();
            printUnExecutedTasks(tasks);
        }
        System.out.println("thread main 线程池完全关闭");
    }

    private static void printUnExecutedTasks(List<Runnable> waitingTasks) {
        for (Runnable waitingTask : waitingTasks) {
            Task task = (Task) waitingTask;
            System.out.println("thread main 还未执行的任务：task " + task.getNum());
        }
    }

    static class Task implements Runnable {

        final private int num;

        private Random random = new Random();

        public Task(int num) {
            this.num = num;
        }

        public int getNum() {
            return num;
        }

        @Override
        public void run() {
            final int waitSec = random.nextInt(5);
            try {
                System.out.println("thread " + Thread.currentThread().getId() + " task " + this.num + " sleeping " + waitSec + "秒");
                TimeUnit.SECONDS.sleep(waitSec);
                System.out.println("thread " + Thread.currentThread().getId() + " task " + this.num + " sleep completed");
            } catch (InterruptedException e) {
                System.out.println("thread " + Thread.currentThread().getId() + " task " + this.num + " was intercepted");
            }
        }
    }
}
